package com.shrct.businessprocess.product.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.product.RCDerivedFullServiceProductSpecification;
import com.shrct.businessprocess.product.RCFullService;
import com.shrct.businessprocess.product.RCFullServiceProductEntry;
import com.shrct.businessprocess.product.RCLogicProduct;
import com.shrct.businessprocess.product.RCRegisterProductServiceEvent;
import com.shrct.businessprocess.product.impl.RCFullServiceProductEntryImpl;
import com.shrct.businessprocess.product.impl.RCLogicProductImpl;
import com.shrct.businessprocess.product.impl.RCRegisterProductServiceEventImpl;
import com.shrct.businessprocess.product.proxy.RCFullServiceProxy;
import com.uniquesoft.uidl.validation.Validates;
import edu.fudan.langlab.domain.common.DateRange;
import edu.fudan.langlab.domain.security.ISystemUserService;
import edu.fudan.langlab.domain.security.User;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;
import org.springframework.beans.factory.BeanFactory;

@Entity
@DiscriminatorValue("RCFULLSERVICE_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcfullservice")
public class RCFullServiceImpl extends BaseModelObject implements RCFullService {
  public RCFullServiceImpl() {
    super();
  }
  
  public RCFullServiceImpl(final RCLogicProduct sourceProduct) {
    super();
    this.sourceProduct = sourceProduct;
  }
  
  private String name;
  
  public String getName() {
    return this.name;
  }
  
  public RCFullService setName(final String name) {
    this.name = name;
    return this;			
    
  }
  
  @JoinColumn(name = "sourceProduct_id")
  @ManyToOne(targetEntity = RCLogicProductImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCLogicProduct sourceProduct;
  
  public RCLogicProduct getSourceProduct() {
    return this.sourceProduct;
  }
  
  public RCFullService setSourceProduct(final RCLogicProduct sourceProduct) {
    this.sourceProduct = sourceProduct;
    return this;			
    
  }
  
  @OneToMany(targetEntity = RCFullServiceProductEntryImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "fullService")
  private Collection<RCFullServiceProductEntry> entries = new java.util.ArrayList<com.shrct.businessprocess.product.RCFullServiceProductEntry>();;
  
  public Collection<RCFullServiceProductEntry> getEntries() {
    return this.entries;
  }
  
  public RCFullServiceProductEntry createAndAddtoEntries(final String projectid) {
    getEntries().size();
    com.shrct.businessprocess.product.RCFullServiceProductEntry rCFullServiceProductEntry = new com.shrct.businessprocess.product.impl.RCFullServiceProductEntryImpl(projectid,this);
    getObjectFactory().create(rCFullServiceProductEntry);
    getEntries().add(rCFullServiceProductEntry);
    return rCFullServiceProductEntry;
    
  }
  
  public RCFullServiceProductEntry createAndAddtoEntries(final String projectid, final Procedure1<RCFullServiceProductEntry> updater) {
    getEntries().size();
    com.shrct.businessprocess.product.RCFullServiceProductEntry rCFullServiceProductEntry = new com.shrct.businessprocess.product.impl.RCFullServiceProductEntryImpl(projectid,this);
    getObjectFactory().create(rCFullServiceProductEntry);
    getEntries().add(rCFullServiceProductEntry);
    return rCFullServiceProductEntry;
    
  }
  
  public RCFullService removeAllEntries() {
    for(RCFullServiceProductEntry obj : this.entries){
    	getObjectFactory().delete(obj);
    }
    this.entries.clear();
    return this;	
    
  }
  
  public RCFullService removeFromEntries(final RCFullServiceProductEntry rCFullServiceProductEntry) {
    this.entries.remove(rCFullServiceProductEntry);
    getObjectFactory().delete(rCFullServiceProductEntry);
    return this;
    
  }
  
  public RCFullServiceProductEntry registerFullServiceProduct(final String projectid, final String serviceContraceCode, final RCDerivedFullServiceProductSpecification type, final Date startDate, final Date dueDate) {
    RCFullServiceProductEntry _xblockexpression = null;
    {
      boolean _notEquals = (!Objects.equal(projectid, null));
      Validates.Assert(_notEquals, "\u65E0\u6548\u9879\u76EE\u7F16\u53F7");
      boolean _notEquals_1 = (!Objects.equal(type, null));
      Validates.Assert(_notEquals_1, "\u670D\u52A1\u7F16\u53F7\u4E0D\u80FD\u4E3A\u7A7A");
      boolean _notEquals_2 = (!Objects.equal(startDate, null));
      Validates.Assert(_notEquals_2, "\u670D\u52A1\u5F00\u59CB\u65E5\u671F\u4E0D\u80FD\u4E3A\u7A7A");
      boolean _notEquals_3 = (!Objects.equal(dueDate, null));
      Validates.Assert(_notEquals_3, "\u670D\u52A1\u7ED3\u675F\u65E5\u671F\u4E0D\u80FD\u4E3A\u7A7A");
      DateRange _dateRange = new DateRange();
      final Procedure1<DateRange> _function = new Procedure1<DateRange>() {
          public void apply(final DateRange it) {
            it.setStartDate(startDate);
            it.setFinishDate(dueDate);
          }
        };
      final DateRange newRange = ObjectExtensions.<DateRange>operator_doubleArrow(_dateRange, _function);
      RCFullServiceProductEntry _createAndAddtoEntries = this.createAndAddtoEntries(projectid);
      final Procedure1<RCFullServiceProductEntry> _function_1 = new Procedure1<RCFullServiceProductEntry>() {
          public void apply(final RCFullServiceProductEntry productService) {
            productService.setServiceContractCode(serviceContraceCode);
            productService.setType(type);
            productService.setStart(startDate);
            productService.setEnd(dueDate);RCRegisterProductServiceEvent rCRegisterProductServiceEvent=RCRegisterProductServiceEventImpl.create(RCFullServiceImpl.this.sourceProduct,productService,getObjectFactory());
            final Procedure1<RCRegisterProductServiceEvent> _function = new Procedure1<RCRegisterProductServiceEvent>() {
                public void apply(final RCRegisterProductServiceEvent it) {
                  Date _day = DateUtil.today();
                  it.setDate(_day);
                  BeanFactory _beanFactory = RCFullServiceImpl.this.getBeanFactory();
                  ISystemUserService _bean = _beanFactory.<ISystemUserService>getBean(ISystemUserService.class);
                  User _currentUser = _bean.getCurrentUser();
                  it.setOperator(_currentUser);
                }
              };
            ObjectExtensions.<RCRegisterProductServiceEvent>operator_doubleArrow(rCRegisterProductServiceEvent, _function);
          }
        };
      RCFullServiceProductEntry _doubleArrow = ObjectExtensions.<RCFullServiceProductEntry>operator_doubleArrow(_createAndAddtoEntries, _function_1);
      _xblockexpression = (_doubleArrow);
    }
    return _xblockexpression;
  }
  
  public static RCFullService create(final RCLogicProduct sourceProduct, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.product.RCFullService rCFullService = new com.shrct.businessprocess.product.impl.RCFullServiceImpl(
    	sourceProduct
    );
    objectFactory.create(rCFullService);
    return rCFullService;			
    
  }
  
  public static RCFullService createRCFullServiceImpl(final RCLogicProduct sourceProduct, final IObjectFactory objectFactory, final Procedure1<RCFullService> init) {
    com.shrct.businessprocess.product.RCFullService rCFullService = new com.shrct.businessprocess.product.impl.RCFullServiceImpl(
    	sourceProduct
    );
    objectFactory.create(rCFullService);
    init.apply(rCFullService);
    
    return rCFullService;			
    
  }
  
  public RCFullServiceProxy toProxy() {
    com.shrct.businessprocess.product.proxy.RCFullServiceProxy proxy = new com.shrct.businessprocess.product.proxy.RCFullServiceProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
